package com.zhuanzhuan.hero.user.facade;

import com.bj58.spat.scf.server.contract.annotation.ServiceBehavior;
import com.bj58.youpin.common.rpc.result.Result;
import com.bj58.zhuanzhuan.zzentry.common.service.entity.ServiceHeaderEntity;
import com.bj58.zhuanzhuan.zzentry.common.service.entity.ZZOpenScfBaseResult;
import com.bj58.zhuanzhuan.zzentry.common.service.model.openEntry.ZZHeader;
import com.bj58.zhuanzhuan.zzentry.common.service.model.openEntry.ZZMethod;
import com.bj58.zhuanzhuan.zzentry.common.service.model.openEntry.ZZParam;
import com.zhuanzhuan.hero.user.dto.label.AddFraternityAuthLabelDTO;
import com.zhuanzhuan.hero.user.dto.label.AuthenticatedLabelsDTO;
import com.zhuanzhuan.hero.user.dto.label.BindFraternityAuthLabelDTO;
import com.zhuanzhuan.hero.user.dto.label.CancelAuthenticatedLabelDTO;
import com.zhuanzhuan.hero.user.enums.ExceptionMsgEnum;
import com.zhuanzhuan.hero.user.helper.ZzLockHelper;
import com.zhuanzhuan.hero.user.service.IFraternityAuthService;
import com.zhuanzhuan.hero.user.util.ServiceHeaderUtil;
import com.zhuanzhuan.hero.user.vo.PageResultWrapper;
import com.zhuanzhuan.hero.user.vo.UserListItemVO;
import com.zhuanzhuan.hero.user.vo.label.CertificationQualifiedVO;
import com.zhuanzhuan.hero.user.vo.label.FraternityAuthLabelVO;
import com.zhuanzhuan.hero.user.vo.label.ToAuthFraternityAuthLabelVO;
import com.zhuanzhuan.hero.user.vo.label.UserFraternityAuthLabelVO;
import com.zhuanzhuan.zzlock.lock.ZZEtcdLock;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName FraternityAuthFacadeImpl
 * @Description
 * @Author hanjunjun
 * @Date 2024/7/2 17:15
 */
@ServiceBehavior
@Slf4j
public class FraternityAuthFacadeImpl implements IFraternityAuthFacade {

    @Resource
    private IFraternityAuthService fraternityAuthService;

    @Resource
    private ZzLockHelper lockHelper;

    @ZZMethod(value = "queryFraternityAuthLabels", desc = "查询用户所有标签和被认证次数", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<List<FraternityAuthLabelVO>> queryFraternityAuthLabels(@ZZHeader ServiceHeaderEntity header,
        Long targetUid) {
        if (Objects.isNull(targetUid)) {
            //不是客态看别人的就是自己看自己的
            targetUid = ServiceHeaderUtil.parseUid(header);
        }

        return ZZOpenScfBaseResult.buildSucc(fraternityAuthService.queryBoundedFraternityAuthLabels(targetUid));
    }

    @ZZMethod(value = "queryUserFraternityAuthLabels", desc = "查询标签和绑定状态", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<List<UserFraternityAuthLabelVO>> queryUserFraternityAuthLabels(@ZZHeader ServiceHeaderEntity header) {
        return ZZOpenScfBaseResult.buildSucc(fraternityAuthService.queryUserFraternityAuthLabels(ServiceHeaderUtil.parseUid(header)));
    }

    @ZZMethod(value = "addFraternityAuthLabel", desc = "新增一个标签", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<UserFraternityAuthLabelVO> addFraternityAuthLabel(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") @Valid AddFraternityAuthLabelDTO addFraternityAuthLabelDTO) {
        UserFraternityAuthLabelVO vo = fraternityAuthService.addFraternityAuthLabel(ServiceHeaderUtil.parseUid(header),
            addFraternityAuthLabelDTO.getLabelName(), header);
        return ZZOpenScfBaseResult.buildSucc(vo);
    }

    @ZZMethod(value = "delFraternityAuthLabel", desc = "删除一个标签", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<Boolean> delFraternityAuthLabel(@ZZHeader ServiceHeaderEntity header, @NotNull Long labelId) {
        fraternityAuthService.delFraternityAuthLabel(ServiceHeaderUtil.parseUid(header), labelId);
        return ZZOpenScfBaseResult.buildSucc(true);
    }

    @ZZMethod(value = "bindFraternityAuthLabels", desc = "绑定同行认证标签", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<Boolean> bindFraternityAuthLabels(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") @Valid BindFraternityAuthLabelDTO dto) {
        fraternityAuthService.bindFraternityAuthLabels(ServiceHeaderUtil.parseUid(header), dto.getLabelIds());
        return ZZOpenScfBaseResult.buildSucc(true);
    }

    @ZZMethod(value = "hasCertificationQualified", desc = "是否有资格认证", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<CertificationQualifiedVO> hasCertificationQualified(@ZZHeader ServiceHeaderEntity header,
        Long homemakerUid) {
        return ZZOpenScfBaseResult.buildSucc(fraternityAuthService.hasCertificationQualified(ServiceHeaderUtil.parseUid(header), homemakerUid));
    }

    @ZZMethod(value = "queryToAuthFraternityAuthLabel", desc = "客态查询已认证过的和未认证的", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<ToAuthFraternityAuthLabelVO> queryToAuthFraternityAuthLabel(@ZZHeader ServiceHeaderEntity header,
        @NotNull Long homemakerUid) {
        return ZZOpenScfBaseResult.buildSucc(fraternityAuthService.queryToAuthFraternityAuthLabel(ServiceHeaderUtil.parseUid(header),
            homemakerUid));
    }

    @ZZMethod(value = "authenticatedLabels", desc = "客态认证同行认证标签", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<Boolean> authenticatedLabels(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") @Valid AuthenticatedLabelsDTO authenticatedLabelsDTO) {
        Long fromUid = ServiceHeaderUtil.parseUid(header);
        Long toUid = authenticatedLabelsDTO.getHomemakerUid();
        try (ZZEtcdLock lock = lockHelper.getLock(String.format("authenticatedLabels_%s_%s", fromUid, toUid))) {
            if (!lock.tryLock()) {
                log.info("获取锁失败");
                return ZZOpenScfBaseResult.buildErr(ExceptionMsgEnum.COMMON_ERROR.getCode(), ExceptionMsgEnum.COMMON_ERROR.getErrorMsg());
            }
            fraternityAuthService.authenticatedLabels(fromUid, toUid, authenticatedLabelsDTO.getLabelIds());
            return ZZOpenScfBaseResult.buildSucc(true);
        }
    }

    @ZZMethod(value = "cancelAuthenticatedLabels", desc = "客态取消认证", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<Boolean> cancelAuthenticatedLabels(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") @Valid CancelAuthenticatedLabelDTO cancelAuthenticatedLabelDTO) {
        Long fromUid = ServiceHeaderUtil.parseUid(header);
        Long toUid = cancelAuthenticatedLabelDTO.getHomemakerUid();
        try (ZZEtcdLock lock = lockHelper.getLock(String.format("cancelAuthenticatedLabels_%s_%s", fromUid, toUid))) {
            if (!lock.tryLock()) {
                log.info("获取锁失败");
                return ZZOpenScfBaseResult.buildErr(ExceptionMsgEnum.COMMON_ERROR.getCode(), ExceptionMsgEnum.COMMON_ERROR.getErrorMsg());
            }
            fraternityAuthService.cancelAuthenticatedLabels(fromUid, cancelAuthenticatedLabelDTO);
            return ZZOpenScfBaseResult.buildSucc(true);
        }
    }

    @Override
    public Result<PageResultWrapper<UserListItemVO>> queryAuthenticatedUsers(Long uid, Integer pageNum, Integer pageSize) {
        return Result.success(fraternityAuthService.queryAuthenticatedUsers(uid, pageNum, pageSize));
    }

    @Override
    public Result<Integer> queryAuthenticatedNum(Long uid) {
        return Result.success(fraternityAuthService.queryAuthenticatedNum(uid));
    }
}
